package io.github.uicdb.et.item_data;

import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import io.github.uicdb.et.ModElements;
import io.github.uicdb.et.ModItemDataComponents;
import io.github.uicdb.et.element.BasicElement;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import net.minecraft.ChatFormatting;
import net.minecraft.core.Holder;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.component.TooltipProvider;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.event.entity.player.ItemTooltipEvent;
import org.jetbrains.annotations.NotNull;

import java.util.Objects;
import java.util.function.Consumer;

@RequiredArgsConstructor
@Getter
public class ItemElementData  {

    public static final Codec<ItemElementData> CODEC = RecordCodecBuilder.create(ins -> ins.group(
            BasicElement.HOLDER_CODEC.fieldOf("element").forGetter(o -> o.element),
            Codec.INT.fieldOf("amount").forGetter(o -> o.amount),
            Codec.INT.fieldOf("ticks").forGetter(o -> o.ticks)
    ).apply(ins, ItemElementData::new));

    public ItemElementData(ModElements element,int amount, int ticks) {
        this.amount = amount;
        this.element = element.holder();
        this.ticks = ticks;
    }

    public static final StreamCodec<RegistryFriendlyByteBuf, ItemElementData> STREAM_CODEC = StreamCodec.composite(
            BasicElement.HOLDER_STREAM_CODEC,
            ItemElementData::getElement,
            ByteBufCodecs.VAR_INT,
            ItemElementData::getAmount,
            ByteBufCodecs.VAR_INT,
            ItemElementData::getTicks,
            ItemElementData::new
    );

    private final Holder<BasicElement> element;
    private final int amount;
    private final int ticks;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof ItemElementData data)) return false;
        return Objects.equals(getElement().getKey().location(), data.getElement().getKey().location());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getElement().getKey().location(), getAmount(), getTicks());
    }

    @Override
    public String toString() {
        return "ItemElementData{" +
                "amount=" + amount +
                ", element=" + element.getKey().location() +
                ", ticks=" + ticks +
                '}';
    }


    public void addToTooltip(Item.@NotNull TooltipContext tooltipContext, @NotNull Consumer<Component> consumer, @NotNull TooltipFlag tooltipFlag) {
        consumer.accept(
                Component.translatable("text.elemental_theory.element_data.0").append(element.value().getName().withStyle(ChatFormatting.GOLD))
        );
        consumer.accept(
                Component.translatable("text.elemental_theory.element_data.1").append(Component.literal(""+amount).withStyle(ChatFormatting.GOLD))
        );
        consumer.accept(
            Component.translatable("text.elemental_theory.element_data.2").append(Component.literal(((float) ticks) / 20f + "s").withStyle(ChatFormatting.GRAY))
        );
    }

    @EventBusSubscriber(bus = EventBusSubscriber.Bus.GAME)
    private static class Handler {
        @SubscribeEvent
        public static void onTooltip(ItemTooltipEvent event) {
            if (event.getItemStack().has(ModItemDataComponents.ITEM_ELEMENT_DATA))
                event.getItemStack().get(ModItemDataComponents.ITEM_ELEMENT_DATA)
                        .addToTooltip(event.getContext(), event.getToolTip()::add, event.getFlags());
        }

    }
}
